#include "file_handle.h"

#include "file_description.h"
#include "file_operate.h"
#include "file_errno.h"
#include <sys/stat.h>
#include <memory>

FileHandle::FileHandle(const std::string & file_name) : m_read_buffer(1024 * 10)
{
    m_file_name = file_name;
}
FileHandle::FileHandle(const std::string & filename, int buffer_size): m_read_buffer(buffer_size > 0 ? buffer_size : 1024 * 10)
{
    m_file_name = filename;
}

int FileHandle::OpenFileOnlyRead()
{
    m_description = std::make_shared<FileDescription>(m_file_name, FileDescription::ONLYRD);
    int result    = m_description->CreateDescription();
    if (result < 0)
    {
        result = EmFileErrno::EmFileErrno_OPEN_FAIL;
    }
    else
    {
        result         = EmFileErrno::EmFileErrno_SUCCESS;
        m_file_operate = std::make_shared<FileOperate>(m_description);
    }
    return result;
}

int FileHandle::OpenFileReadWrite()
{
    m_description = std::make_shared<FileDescription>(m_file_name, FileDescription::RDWR);
    int result    = m_description->CreateDescription();
    if (result < 0)
    {
        result = EmFileErrno::EmFileErrno_OPEN_FAIL;
    }
    else
    {
        result         = EmFileErrno::EmFileErrno_SUCCESS;
        m_file_operate = std::make_shared<FileOperate>(m_description);
    }
    return result;
}

int FileHandle::OpenFileAppendWrite()
{
    m_description = std::make_shared<FileDescription>(m_file_name, FileDescription::WRAPP);
    int result    = m_description->CreateDescription();
    if (result < 0)
    {
        result = EmFileErrno::EmFileErrno_OPEN_FAIL;
    }
    else
    {
        result         = EmFileErrno::EmFileErrno_SUCCESS;
        m_file_operate = std::make_shared<FileOperate>(m_description);
    }
    return result;
}

int FileHandle::Write(const uint8_t * data, int length) const
{
    int result = m_file_operate->Write(data, length);
    return result;
}

int FileHandle::Write(WriteBuffer & buffer) const
{
    int result = m_file_operate->Write(buffer.BufferData(), buffer.BufferDataSize());
    if (result > 0)
    {
        buffer.RemoveSize(result);
    }
    return result;
}

uint8_t * FileHandle::Data(int & length)
{
    int result = m_file_operate->Read(m_read_buffer.BufferEnd(), m_read_buffer.BufferFreeSize());
    if (result == 0)
    {

    }
    else
    {
        m_read_buffer.MovePosition(result);
    }
    if (m_read_buffer.BufferFreeSize() <= 65535)
    {
        m_read_buffer.ExpendBuffer();
    }
    length = m_read_buffer.BufferDataSize();
    return m_read_buffer.BufferData();
}

void FileHandle::RemoveDataLength(int length)
{
    length = length > m_read_buffer.BufferDataSize() ? m_read_buffer.BufferDataSize() : length;
    m_read_buffer.RemoveSize(length);
}

uint64_t FileHandle::GetFileSize() const
{
    if (m_description->DescriptionData() > 0)
    {
        struct stat file_stat = {};
        fstat(m_description->DescriptionData(), &file_stat);
        off_t size = file_stat.st_size;  // 直接获取大小
        return size;
    }
    return 0;
}

int FileHandle::DeleteFile() const
{
    if (m_description->DescriptionData() > 0)
    {
        int result = remove(m_file_name.c_str());
        if (result <= 0)
        {
            return EmFileErrno_DELETE_FAIL;
        }
        m_description->CloseDescription();
        return EmFileErrno_SUCCESS;
    }
    return EmFileErrno_DELETE_FAIL;
}


int FileHandleUtil::MakeDir(const std::string & dir_path)
{
    struct stat st = {};
    if (stat(dir_path.c_str(), &st) == 0)
    {
        if (S_ISDIR(st.st_mode))
        {
            return EmFileErrno_SUCCESS;
        }
    }
    if (mkdir(dir_path.c_str(), 0777) == 0)
    {
        return EmFileErrno_SUCCESS;
    }
    return EmFileErrno_MKDIR_FAIL;
}

